package com.singerw.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.singerw.pojo.MyUserDetails;
import com.singerw.pojo.ResultLoginSuccess;
import com.singerw.service.LogService;
import com.singerw.utils.JwtUtils;
import com.singerw.utils.ResultUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.Date;

/**
 * @version V1.0
 * @Package com.singerw.filter
 * @auhter 张欣
 * @date 2020/12/29-5:40 PM
 * 验证用户名密码正确后，生成一个token，并将token返回给客户端
 * 该类继承自UsernamePasswordAuthenticationFilter，重写了其中的2个方法 ,
 * attemptAuthentication：接收并解析用户凭证。
 * successfulAuthentication：用户成功登录后，这个方法会被调用，我们在这个方法里生成token并返回。
 */

public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {



    private AuthenticationManager authenticationManager;
    private LogService logService;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager, LogService logService) {
        this.authenticationManager = authenticationManager;
        super.setFilterProcessesUrl("/auth/login");
        this.logService = logService;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        // 方法将 request 中的 username 和 password 生成 UsernamePasswordAuthenticationToken 对象，用于 AuthenticationManager 的验证
        String param = null;
        JSONObject jsonObject = (JSONObject) request.getSession().getAttribute("data");
        String username = jsonObject.getString("username");
        String password = jsonObject.getString("password");
        if (username == null) {
            username = "";
        }
        if (password == null) {
            password = "";
        }
        username = username.trim();
        return authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(username, password));
}

    // 成功验证后调用的方法
    // 如果验证成功，就生成token并返回
    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult) throws IOException {

        MyUserDetails user = (MyUserDetails) authResult.getPrincipal();

        String role = "";
        Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
        for (GrantedAuthority authority : authorities) {
            role = authority.getAuthority();
        }
        String username = user.getUsername();
        String userId = user.getId();
        String token = JwtUtils.createToken(userId,username, role);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userName",username);
        jsonObject.put("date",new Date());
        logService.addLog(jsonObject,true);
        String success = ResultUtils.success(new ResultLoginSuccess(username, role, token, "10002460607"));
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        response.getWriter().write(success);

    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        response.getWriter().write(JSON.toJSONString(ResultUtils.fail("用户名或密码错误。")));

    }


}
